﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using PacManLib;

namespace PacManBoardControl
{
    /// <summary>
    /// Holds bitmaps for Pac-Man.
    /// </summary>
    class PacManBitmapManager
    {
        #region Public methods and properties

        /// <summary>
        /// Constructor.
        /// </summary>
        public PacManBitmapManager()
        {
            generatePacManBitmaps();
        }

        /// <summary>
        /// Gets the Pac-Man bitmap to show.
        /// </summary>
        public Bitmap getBitmap(PlayerInfo pacManInfo)
        {
            Bitmap bitmap = null;
            PlayerInfo.Direction direction = pacManInfo.CurrentDirection;
            switch (m_pacManMouthPosition)
            {
                case PacManMouthPosition.Closed:
                    bitmap = m_bmpPacManClosed;
                    break;

                case PacManMouthPosition.OpenMidLow:
                    switch (direction)
                    {
                        case PlayerInfo.Direction.Down:
                            bitmap = m_bmpPacManOpenMidDown;
                            break;
                        case PlayerInfo.Direction.Up:
                            bitmap = m_bmpPacManOpenMidUp;
                            break;
                        case PlayerInfo.Direction.Right:
                            bitmap = m_bmpPacManOpenMidRight;
                            break;
                        case PlayerInfo.Direction.Left:
                            bitmap = m_bmpPacManOpenMidLeft;
                            break;
                    }
                    break;

                case PacManMouthPosition.OpenMidHigh:
                    switch (direction)
                    {
                        case PlayerInfo.Direction.Down:
                            bitmap = m_bmpPacManOpenMidDown;
                            break;
                        case PlayerInfo.Direction.Up:
                            bitmap = m_bmpPacManOpenMidUp;
                            break;
                        case PlayerInfo.Direction.Right:
                            bitmap = m_bmpPacManOpenMidRight;
                            break;
                        case PlayerInfo.Direction.Left:
                            bitmap = m_bmpPacManOpenMidLeft;
                            break;
                    }
                    break;

                case PacManMouthPosition.OpenAll:
                    switch (direction)
                    {
                        case PlayerInfo.Direction.Down:
                            bitmap = m_bmpPacManOpenAllDown;
                            break;
                        case PlayerInfo.Direction.Up:
                            bitmap = m_bmpPacManOpenAllUp;
                            break;
                        case PlayerInfo.Direction.Right:
                            bitmap = m_bmpPacManOpenAllRight;
                            break;
                        case PlayerInfo.Direction.Left:
                            bitmap = m_bmpPacManOpenAllLeft;
                            break;
                    }
                    break;
            }

            return bitmap;
        }

        /// <summary>
        /// Moves Pac-Man's mouth to the next position.
        /// </summary>
        public void nextPacManMouthPosition()
        {
            switch (m_pacManMouthPosition)
            {
                case PacManMouthPosition.Closed:
                    m_pacManMouthPosition = PacManMouthPosition.OpenMidHigh;
                    break;

                case PacManMouthPosition.OpenMidHigh:
                    m_pacManMouthPosition = PacManMouthPosition.OpenAll;
                    break;

                case PacManMouthPosition.OpenAll:
                    m_pacManMouthPosition = PacManMouthPosition.OpenMidLow;
                    break;

                case PacManMouthPosition.OpenMidLow:
                    m_pacManMouthPosition = PacManMouthPosition.Closed;
                    break;
            }
        }

        #endregion

        #region Private functions

        /// <summary>
        /// Creates bitmaps for Pac-Man.
        /// </summary>
        private void generatePacManBitmaps()
        {
            Graphics g;
            SolidBrush b = new SolidBrush(Color.FromArgb(255, 255, 0));
            SolidBrush CoverBrush = new SolidBrush(Color.Black);

            Point p = new Point(-1, -1);

            m_bmpPacManClosed = new Bitmap(PACMAN_WIDTH, PACMAN_HEIGHT);
            g = Graphics.FromImage(m_bmpPacManClosed);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(b, p.X, p.Y, PACMAN_WIDTH, PACMAN_HEIGHT);

            m_bmpPacManOpenMidLeft = new Bitmap(PACMAN_WIDTH, PACMAN_HEIGHT);
            g = Graphics.FromImage(m_bmpPacManOpenMidLeft);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(b, p.X, p.Y, PACMAN_WIDTH, PACMAN_HEIGHT);
            g.FillPie(CoverBrush, p.X - 2, p.Y, 41, 30, 155, 50);
            g.FillRectangle(CoverBrush, p.X, p.Y + 5, 4, 6);
            g.FillRectangle(CoverBrush, p.X, p.Y + 20, 4, 6);

            m_bmpPacManOpenMidRight = (Bitmap)m_bmpPacManOpenMidLeft.Clone();
            m_bmpPacManOpenMidRight.RotateFlip(RotateFlipType.Rotate180FlipNone);
            m_bmpPacManOpenMidRight.MakeTransparent(Color.Black);

            m_bmpPacManOpenMidUp = (Bitmap)m_bmpPacManOpenMidLeft.Clone();
            m_bmpPacManOpenMidUp.RotateFlip(RotateFlipType.Rotate90FlipNone);
            m_bmpPacManOpenMidUp.MakeTransparent(Color.Black);

            m_bmpPacManOpenMidDown = (Bitmap)m_bmpPacManOpenMidLeft.Clone();
            m_bmpPacManOpenMidDown.RotateFlip(RotateFlipType.Rotate270FlipNone);
            m_bmpPacManOpenMidDown.MakeTransparent(Color.Black);

            m_bmpPacManOpenAllLeft = new Bitmap(PACMAN_WIDTH, PACMAN_HEIGHT);
            g = Graphics.FromImage(m_bmpPacManOpenAllLeft);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(b, p.X, p.Y, PACMAN_WIDTH, PACMAN_HEIGHT);
            g.FillPie(CoverBrush, p.X - 2, p.Y, 41, 30, 135, 90);
            g.FillRectangle(CoverBrush, p.X + 2, p.Y, 6, 6);
            g.FillRectangle(CoverBrush, p.X + 2, p.Y + 25, 6, 6);
            m_bmpPacManOpenAllLeft.MakeTransparent(Color.Black);

            m_bmpPacManOpenAllRight = (Bitmap)m_bmpPacManOpenAllLeft.Clone();
            m_bmpPacManOpenAllRight.RotateFlip(RotateFlipType.Rotate180FlipNone);
            m_bmpPacManOpenAllRight.MakeTransparent(Color.Black);

            m_bmpPacManOpenAllUp = (Bitmap)m_bmpPacManOpenAllLeft.Clone();
            m_bmpPacManOpenAllUp.RotateFlip(RotateFlipType.Rotate90FlipNone);
            m_bmpPacManOpenAllUp.MakeTransparent(Color.Black);

            m_bmpPacManOpenAllDown = (Bitmap)m_bmpPacManOpenAllLeft.Clone();
            m_bmpPacManOpenAllDown.RotateFlip(RotateFlipType.Rotate270FlipNone);
            m_bmpPacManOpenAllDown.MakeTransparent(Color.Black);
        }

        #endregion
        
        #region Constants

        // The Pac-Man size...
        private const int PACMAN_WIDTH = 30;
        private const int PACMAN_HEIGHT = 30;

        #endregion

        #region Private data

        // An enum for the Pac-Man's mouth position, so that he can chomp...
        private enum PacManMouthPosition
        {
            Closed,
            OpenMidLow,
            OpenMidHigh,
            OpenAll
        }
        private PacManMouthPosition m_pacManMouthPosition = PacManMouthPosition.Closed;

        // Pac-Man bitmaps...
        private Bitmap m_bmpPacManClosed = null;
        private Bitmap m_bmpPacManOpenMidLeft = null;
        private Bitmap m_bmpPacManOpenMidRight = null;
        private Bitmap m_bmpPacManOpenMidUp = null;
        private Bitmap m_bmpPacManOpenMidDown = null;
        private Bitmap m_bmpPacManOpenAllLeft = null;
        private Bitmap m_bmpPacManOpenAllRight = null;
        private Bitmap m_bmpPacManOpenAllUp = null;
        private Bitmap m_bmpPacManOpenAllDown = null;

        #endregion
    }
}
